﻿#region ExcuteHalconProcParameterDialog.cs
// ============================================================================
// This region will be filled automatically with data if you are working
// for example with Microsoft SourceSafe
//
// Purpose:          
// Specifics: 
// 
// Creation date:    2023/12/4 15:10:02
// Created by:       hao.chen
//
// $Author:        $
// $Date:          $
// $Revision:      $
// $History:       $
// $NoKeywords:    $
// 
// Copyright:      © 2023 YourCompanyName
//                 All Rights Reserved
// ============================================================================
#endregion

using NeuroCheck.PlugInLib.UI;
using System;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;

using HalconDotNet;

using NeuroCheck.PlugInLib.API;
using ControlEdit;
using System.Collections.Generic;
using NeuroCheck.PlugInLib.Base;
using System.Threading.Tasks;
using System.Threading;
using CLVisionHalconNC620.Transform;
using CLVisionHalconNC620.Dialogs;
using CLVisionTrace;
using System.Linq;


// TODO: Namespace - Modify the namespace to the project namespace
namespace CLVisionHalconNC620
{
    [Obfuscation(ApplyToMembers = false)]
    public partial class ExcuteHalconProcParameterDialog : NcPICheckFunctionDialogBase
    {
        public ExcuteHalconProcParameterDialog()
            : base()
        {
            InitializeComponent();
        }

        #region ---------变量----------
        public ExcuteHalconProcParameterProxy ProxyInstance
        {
            get { return m_ProxyInstance; }
            set { m_ProxyInstance = value; }
        }
        private ExcuteHalconProcParameterProxy m_ProxyInstance;

        string selectItem = "";
        public static List<string> showProcedurePath = new List<string>();
        #endregion

        #region ----------参数加载、保存--------------------

        /// <summary>
        /// 加载参数
        /// </summary>
        private void LoadConfiguration()
        {
            string procedureName = m_ProxyInstance.CurrentProcedureName;
            if (procedureName != null)
            {
                //加载当前procedure
                AssemblyInstance.nC_Halcon.LoadProcedureNC(procedureName, out int ErrorCode, out string ErrorText);
                if (ErrorCode ==-1)
                {
                    throw new NcPIUserException($"加载hdvp文件{procedureName}失败！{ErrorText}");
                }
                //获取参数名称,参数名称会传给属性InputIconicNames，OutputIconicNames，InputCtrlNames，OutputCtrlNames
                AssemblyInstance.nC_Halcon.GetProcedureParNamesNC(out int a, out string b);

                //获取参数详情
                LoadDoc();

                SetParToDataGridview(procedureName);
            }
            //刷新procedure列表
            Refresh_ListBox();
        }

        /// <summary>
        /// 保存参数
        /// </summary>
        private void SaveConfiguration()
        {
            try
            {
                var Ls_iconic_Input = DataGridViewEdit.DataGridViewToList(dataGridView_Iconic_Input);
                var Ls_iconic_Output = DataGridViewEdit.DataGridViewToList(dataGridView_Iconic_Output);
                var Ls_control_Input = DataGridViewEdit.DataGridViewToList(dataGridView_Control_Input);
                var Ls_control_Output = DataGridViewEdit.DataGridViewToList(dataGridView_Control_Output);
                var Ls_cfg_Par = DataGridViewEdit.DataGridViewToList_cfg(dataGridView_Cfg);
                var CurrentProcedureName = listBox_Procedures.SelectedItem.ToString();

                m_ProxyInstance.Ls_iconic_Input = Ls_iconic_Input;
                m_ProxyInstance.Ls_iconic_Output = Ls_iconic_Output;
                m_ProxyInstance.Ls_control_Input = Ls_control_Input;
                m_ProxyInstance.Ls_control_Output = Ls_control_Output;
                m_ProxyInstance.Ls_cfg_Par = Ls_cfg_Par;
                m_ProxyInstance.Dic_proceduresPar = new Dictionary<string, (List<(string, string, string)>, List<(string, string, string)>, List<(string, string, string)>, List<(string, string, string)>, List<(string, string, List<string>, string)>)>() { { CurrentProcedureName, (Ls_iconic_Input, Ls_iconic_Output, Ls_control_Input, Ls_control_Output, Ls_cfg_Par) } };
                m_ProxyInstance.CurrentProcedureName = listBox_Procedures.SelectedItem.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "请检查是否有参数未设置", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
            }
            m_ProxyInstance.UpdateSourceObject();
        }

        /// <summary>
        /// 保存已设置的Procedure参数
        /// </summary>
        private void SaveParToDictionary()
        {

            List<(string, string, string)> ls_Iconic_Input = DataGridViewEdit.DataGridViewToList(dataGridView_Iconic_Input);
            List<(string, string, string)> ls_Iconic_Output = DataGridViewEdit.DataGridViewToList(dataGridView_Iconic_Output);
            List<(string, string, string)> ls_Control_Input = DataGridViewEdit.DataGridViewToList(dataGridView_Control_Input);
            List<(string, string, string)> ls_Control_Output = DataGridViewEdit.DataGridViewToList(dataGridView_Control_Output);
            List<(string, string, List<string>, string)> ls_CfgPar = DataGridViewEdit.DataGridViewToList_cfg(dataGridView_Cfg);

            (List<(string, string, string)>, List<(string, string, string)>, List<(string, string, string)>, List<(string, string, string)>, List<(string, string, List<string>, string)>) tempTuple
                = (ls_Iconic_Input, ls_Iconic_Output, ls_Control_Input, ls_Control_Output, ls_CfgPar);


            //判断字典中是否含有当前设置的procedure名称
            if (!m_ProxyInstance.Dic_proceduresPar.ContainsKey(listBox_Procedures.SelectedItem.ToString()))
            {
                m_ProxyInstance.Dic_proceduresPar.Add(listBox_Procedures.SelectedItem.ToString(), tempTuple);
            }
            else
            {
                m_ProxyInstance.Dic_proceduresPar[listBox_Procedures.SelectedItem.ToString()] = tempTuple;
            }
        }

        #endregion

        #region -------------窗体、界面----------
        private void ExcuteHalconProcParameterDialog_Load(object sender, EventArgs e)
        {
            LoadConfiguration();
        }



        /// <summary>
        /// 打开Procedure所在位置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void m_btnOpenFilePath_Click(object sender, EventArgs e)
        {
            //当前程序，所有procedure固定放在一个文件夹
            string procedurePath = ExcuteHalconProcParameterDialog.showProcedurePath[0];
            System.Diagnostics.Process.Start(procedurePath);
        }

        /// <summary>
        /// 刷新Procedure列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void m_btnRefresh_Click(object sender, EventArgs e)
        {
            Refresh_ListBox();
        }

        /// <summary>
        ///   刷新
        /// </summary>
        private void Refresh_ListBox()
        {
            listBox_Procedures.Items.Clear();
            //获取目录下procedure名称
            string[] procedureNames;
            //需要显示procedure的路径

            AssemblyInstance.nC_Halcon.GetProcedureNamesNC(showProcedurePath.ToArray(), out procedureNames, out int ErrorCode, out string ErrorText, SearchOption.TopDirectoryOnly);
            if (ErrorCode == -1)
            {
                // NcPIEventLogAccess.AddWarning(0, this, "测试显示log");
                throw new NcPIUserException(ErrorText);
            }

            toolStripStatusLabel1.Text = $"总数：{procedureNames.Length.ToString()}";
            for (int i = 0; i < procedureNames.Length; i++)
            {
                string procedureName = Path.GetFileNameWithoutExtension(procedureNames[i]);
                listBox_Procedures.Items.Add(procedureName);
            }

            //设置选定项
            string selectName = m_ProxyInstance.CurrentProcedureName;
            if (selectItem == "")
            {
                listBox_Procedures.SelectedItem = selectName;
                selectItem = selectName;
            }
            else
            {
                listBox_Procedures.SelectedItem = selectItem;
            }

        }


        /// <summary>
        /// 应用参数更改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void m_btnApply_Click(object sender, EventArgs e)
        {
            SaveParToDictionary();
            string ErrorText;
            bool limit;

            #region iconic输入参数
            m_ProxyInstance.Ls_iconic_Input = DataGridViewEdit.DataGridViewToList(dataGridView_Iconic_Input, out ErrorText);
            if (ErrorText != "")
            {
                MessageBox.Show(ErrorText);
                return;
            }
            //判断值是否在范围内
            limit = DataGridViewEdit.ValueLimit(dataGridView_Iconic_Input, out ErrorText);
            if (!limit)
            {
                MessageBox.Show(ErrorText);
                return;
            }
            #endregion

            #region iconic输出参数
            m_ProxyInstance.Ls_iconic_Output = DataGridViewEdit.DataGridViewToList(dataGridView_Iconic_Output, out ErrorText);
            if (ErrorText != "")
            {
                MessageBox.Show(ErrorText);
                return;
            }
            //判断值是否在范围内
            limit = DataGridViewEdit.ValueLimit(dataGridView_Iconic_Output, out ErrorText);
            if (!limit)
            {
                MessageBox.Show(ErrorText);
                return;
            }
            #endregion

            #region control输入参数
            m_ProxyInstance.Ls_control_Input = DataGridViewEdit.DataGridViewToList(dataGridView_Control_Input, out ErrorText);
            if (ErrorText != "")
            {
                MessageBox.Show(ErrorText);
                return;
            }
            //判断值是否在范围内
            limit = DataGridViewEdit.ValueLimit(dataGridView_Control_Input, out ErrorText);
            if (!limit)
            {
                MessageBox.Show(ErrorText);
                return;
            }
            #endregion

            #region control输出参数
            m_ProxyInstance.Ls_control_Output = DataGridViewEdit.DataGridViewToList(dataGridView_Control_Output, out ErrorText);
            if (ErrorText != "")
            {
                MessageBox.Show(ErrorText);
                return;
            }
            //判断值是否在范围内
            limit = DataGridViewEdit.ValueLimit(dataGridView_Control_Output, out ErrorText);
            if (!limit)
            {
                MessageBox.Show(ErrorText);
                return;
            }
            #endregion


            m_ProxyInstance.Ls_cfg_Par = DataGridViewEdit.DataGridViewToList_cfg(dataGridView_Cfg, out ErrorText);
            if (ErrorText != "")
            {
                MessageBox.Show(ErrorText);
                return;
            }


            label_Apply.Text = "参数应用成功";
            Task.Run(() =>
            {
                Thread.Sleep(800);
                if (this.IsHandleCreated)
                {
                    this.BeginInvoke(new Action(() =>
                    {
                        this.label_Apply.Text = "";

                    }));
                }
            });

        }

        /// <summary>
        /// OK按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void m_btnOK_Click(object sender, EventArgs e)
        {
            SaveConfiguration();
        }

        #endregion

        #region --------procedurea切换，参数的更新----------

        /// <summary>
        /// 选中ListBox中选项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBox_Procedures_MouseClick(object sender, MouseEventArgs e)
        {
            //已经处于选中状态，再次点击不做处理
            if (listBox_Procedures.SelectedItem.ToString() == selectItem)
            {
                return;
            }

            int posindex = listBox_Procedures.IndexFromPoint(new Point(e.X, e.Y));
            if (posindex >= 0 && posindex < listBox_Procedures.Items.Count)
            {
                listBox_Procedures.SelectedIndex = posindex;
                selectItem = listBox_Procedures.SelectedItem.ToString();
                ClearPar();
                //加载当前procedure
                AssemblyInstance.nC_Halcon.LoadProcedureNC(selectItem, out int ErrorCode, out string ErrorText);
                //判断存储的字典中，是否含有当前选中的procedure
                if (m_ProxyInstance.Dic_proceduresPar.ContainsKey(selectItem))
                {
                    Refresh_Procedure_Parameter(selectItem, true);
                    LoadDoc();
                }
                else
                {
                    //ExcuteHalconProc.nC_Halcon.LoadProcedureNC(selectItem, out int ErrorCode, out string ErrorText);
                    if (ErrorCode == -1)
                    {
                        throw new NcPIUserException($"加载procedure异常{ErrorText}");
                    }
                    Refresh_Procedure_Parameter(selectItem, false);
                    LoadDoc();
                }
            }
            else
            {
                listBox_Procedures.SelectedIndex = posindex;
                selectItem = "";
            }
        }
        /// <summary>
        /// 获取参数详情
        /// </summary>
        private void LoadDoc()
        {
            textBox_Description.Clear();
            HTuple hTuple;
            //基础-详细的描述
            hTuple = AssemblyInstance.nC_Halcon.GetHDevProcedureNC().GetInfo("abstract");
            string info_abs = hTuple.Length == 0 ? "" : hTuple.S;
            textBox_Description.AppendText("功能描述：" + info_abs + "\r\n");

            hTuple = AssemblyInstance.nC_Halcon.InputIconicNames;
            ShowParDescription(hTuple);

            hTuple = AssemblyInstance.nC_Halcon.OutputIconicNames;
            ShowParDescription(hTuple);

            hTuple = AssemblyInstance.nC_Halcon.InputCtrlNames;
            ShowParDescription(hTuple);

            hTuple = AssemblyInstance.nC_Halcon.OutputCtrlNames;
            ShowParDescription(hTuple);
        }

        /// <summary>
        /// 获取参数详细信息显示到界面
        /// </summary>
        /// <param name="hTuple"></param>
        private void ShowParDescription(HTuple hTuple)
        {
            for (int i = 0; i < hTuple.Length; i++)
            {
                //获取参数的描述
                HTuple hTupleInfo = AssemblyInstance.nC_Halcon.GetHDevProcedureNC().GetParamInfo(hTuple[i], "description");
                string info = hTupleInfo.Length == 0 ? "" : hTupleInfo.S;
                textBox_Description.AppendText($"{hTuple[i].S} : {info}\r\n");
            }
        }

        /// <summary>
        /// 清除datagridview
        /// </summary>
        private void ClearPar()
        {
            dataGridView_Iconic_Input.Rows.Clear();
            dataGridView_Iconic_Output.Rows.Clear();
            dataGridView_Control_Input.Rows.Clear();
            dataGridView_Control_Output.Rows.Clear();
            dataGridView_Cfg.Rows.Clear();
        }
        /// <summary>
        /// 将保存的设置参数写入Datagridview
        /// </summary>
        /// <param name="procedureName">procedure的名称，判断字典中是否已保存该procedure参数</param>
        /// <param name="loadFromDic">是否从字典中加载参数</param>
        private void Refresh_Procedure_Parameter(string procedureName, bool loadFromDic)
        {
            //获取参数名称,参数名称会传给属性InputIconicNames，OutputIconicNames，InputCtrlNames，OutputCtrlNames
            AssemblyInstance.nC_Halcon.GetProcedureParNamesNC(out int a, out string b);

            if (loadFromDic)
            {
                SetParToDataGridview(procedureName);
            }
            else
            {

                //输入图像参数
                HTuple InputIconicHTuple = AssemblyInstance.nC_Halcon.InputIconicNames;
                for (int i = 0; i < InputIconicHTuple.Length; i++)
                {
                    DataGridViewEdit.DataGridViewSet(InputIconicHTuple[i].S, new string[] { "Tray" }, "Tray", "", dataGridView_Iconic_Input);
                }

                //输出图像参数
                HTuple OutputIconicHTuple = AssemblyInstance.nC_Halcon.OutputIconicNames;
                for (int i = 0; i < OutputIconicHTuple.Length; i++)
                {
                    DataGridViewEdit.DataGridViewSet(OutputIconicHTuple[i].S, new string[] { "Tray" }, "Tray", "", dataGridView_Iconic_Output);
                }


                //输入控制参数
                HTuple InputCtrlHTuple = AssemblyInstance.nC_Halcon.InputCtrlNames;
                for (int i = 0; i < InputCtrlHTuple.Length; i++)
                {
                    if (InputCtrlHTuple[i].S.ToLower().Contains("cfg"))
                    {
                        //获取Halcon参数数组，做下拉框显示
                        HTuple values = AssemblyInstance.nC_Halcon.GetHDevProcedureNC().GetInputCtrlParamInfo(i + 1, "values");
                        //获取Halcon参数类型
                        HTuple typeList = AssemblyInstance.nC_Halcon.GetHDevProcedureNC().GetInputCtrlParamInfo(i + 1, "type_list");

                        List<string> ls = new List<string>();
                        if (values?.Length > 1)
                        {
                            for (int j = 0; j < values.Length; j++)
                            {
                                ls.Add(values[j].S);
                            }
                            DataGridViewEdit.DataGridViewSet_Cfg(InputCtrlHTuple[i].S, ls.ToArray(), (typeList == null || typeList.Length == 0) ? "" : typeList.S, dataGridView_Cfg);
                        }
                        else
                        {
                            int rowIndex = dataGridView_Cfg.Rows.Add();
                            dataGridView_Cfg.Rows[rowIndex].Cells[0].Value = InputCtrlHTuple[i].S;
                            dataGridView_Cfg.Rows[rowIndex].Cells[2].Value = (typeList == null || typeList.Length == 0) ? "" : typeList.S;
                        }
                    }
                    else
                    {
                        DataGridViewEdit.DataGridViewSet(InputCtrlHTuple[i].S, new string[] { "Tray", "Register" }, "Register", "", dataGridView_Control_Input);
                    }
                }

                //输出控制参数
                HTuple OutputCtrlHTuple = AssemblyInstance.nC_Halcon.OutputCtrlNames;
                for (int i = 0; i < OutputCtrlHTuple.Length; i++)
                {
                    DataGridViewEdit.DataGridViewSet(OutputCtrlHTuple[i].S, new string[] { "Tray", "Register" }, "Register", "", dataGridView_Control_Output);
                }
            }
        }

        /// <summary>
        /// 设置参数到DataGridview
        /// </summary>
        /// <param name="procedureName"></param>
        private void SetParToDataGridview(string procedureName)
        {

            try
            {
                #region 将存储的iconic和control参数写入datagridview
                SetIconicParToDataGridview(procedureName, "in");
                SetIconicParToDataGridview(procedureName, "out");
                SetInputCtrlParToDataGridview(procedureName);
                SetOutputCtrlParToDataGridview(procedureName);
                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "参数加载异常", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
            }

            try
            {
                SetCfgParToDataGridview(procedureName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "cfg参数加载异常", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
            }
        }




        /// <summary>
        /// 设置Iconic参数
        /// </summary>
        /// <param name="procedureName">procedure名称</param>
        /// <param name="inOrOut">输入/输出参数</param>
        private void SetIconicParToDataGridview(string procedureName, string inOrOut)
        {
            List<(string, string, string)> Ls_iconic = new List<(string, string, string)>();
            HTuple IconicHTuple = new HTuple();
            if (inOrOut == "in")
            {
                //Item1为字典存储的图像参数
                Ls_iconic = m_ProxyInstance.Dic_proceduresPar[procedureName].Item1;
                //Halcon输入图像参数
                IconicHTuple = AssemblyInstance.nC_Halcon.InputIconicNames;
            }
            else if (inOrOut == "out")
            {
                Ls_iconic = m_ProxyInstance.Dic_proceduresPar[procedureName].Item2;
                IconicHTuple = AssemblyInstance.nC_Halcon.OutputIconicNames;
            }

            DataGridView dataGridView_Iconic = new DataGridView();
            if (inOrOut == "in")
            {
                dataGridView_Iconic = dataGridView_Iconic_Input;
            }
            else if (inOrOut == "out")
            {
                dataGridView_Iconic = dataGridView_Iconic_Output;
            }
            bool isAdd = true;
            for (int i = 0; i < IconicHTuple.Length; i++)
            {
                for (int j = 0; j < Ls_iconic.Count; j++)
                {
                    if (IconicHTuple[i].S == Ls_iconic[j].Item1)
                    {
                        DataGridViewEdit.DataGridViewSet(Ls_iconic[j].Item1, new string[] { "Tray" }, Ls_iconic[j].Item2, Ls_iconic[j].Item3, dataGridView_Iconic);
                        isAdd = false;
                    }
                }
                if (isAdd)
                {
                    DataGridViewEdit.DataGridViewSet(IconicHTuple[i], new string[] { "Tray" }, "Tray", "", dataGridView_Iconic);
                }
                isAdd = true;
            }
        }


        /// <summary>
        /// 设置Control输入参数
        /// </summary>
        /// <param name="procedureName"></param>
        private void SetInputCtrlParToDataGridview(string procedureName)
        {
            List<(string, string, string)> Ls_control_Input = m_ProxyInstance.Dic_proceduresPar[procedureName].Item3;
            //输入控制参数
            HTuple InputCtrlHTuple = AssemblyInstance.nC_Halcon.InputCtrlNames;
            bool isAdd = true;
            for (int i = 0; i < InputCtrlHTuple.Length; i++)
            {
                for (int j = 0; j < Ls_control_Input.Count; j++)
                {
                    if (!InputCtrlHTuple[i].S.ToLower().Contains("cfg") && InputCtrlHTuple[i].S == Ls_control_Input[j].Item1)
                    {
                        DataGridViewEdit.DataGridViewSet(Ls_control_Input[j].Item1, new string[] { "Tray", "Register" }, Ls_control_Input[j].Item2, Ls_control_Input[j].Item3, dataGridView_Control_Input);
                        isAdd = false;
                    }
                }
                if (!InputCtrlHTuple[i].S.ToLower().Contains("cfg") && isAdd)
                {
                    DataGridViewEdit.DataGridViewSet(InputCtrlHTuple[i], new string[] { "Tray", "Register" }, "Register", "", dataGridView_Control_Input);
                }
                isAdd = true;
            }

        }


        /// <summary>
        /// 设置Control输出参数
        /// </summary>
        /// <param name="procedureName"></param>
        private void SetOutputCtrlParToDataGridview(string procedureName)
        {
            List<(string, string, string)> Ls_control_Output = m_ProxyInstance.Dic_proceduresPar[procedureName].Item4;
            //输出控制参数
            HTuple OutputCtrlHTuple = AssemblyInstance.nC_Halcon.OutputCtrlNames;
            //是否为新增的参数
            bool isAdd = true;
            //遍历新的hdvp的参数
            for (int i = 0; i < OutputCtrlHTuple.Length; i++)
            {
                //遍历存储的参数
                for (int j = 0; j < Ls_control_Output.Count; j++)
                {
                    //如果新的参数，在存储中出现，则显示存储的
                    if (OutputCtrlHTuple[i].S == Ls_control_Output[j].Item1)
                    {
                        DataGridViewEdit.DataGridViewSet(Ls_control_Output[j].Item1, new string[] { "Tray", "Register" }, Ls_control_Output[j].Item2, Ls_control_Output[j].Item3, dataGridView_Control_Output);
                        //新增参数置为false
                        isAdd = false;
                    }
                }
                if (isAdd)
                {
                    DataGridViewEdit.DataGridViewSet(OutputCtrlHTuple[i], new string[] { "Tray", "Register" }, "Register", "", dataGridView_Control_Output);
                }
                //遍历下一个新增参数时，isAdd置为true
                isAdd = true;
            }
        }

        /// <summary>
        /// 设置cfg参数
        /// </summary>
        /// <param name="procedureName"></param>
        private void SetCfgParToDataGridview(string procedureName)
        {
            //字典中存储的cfg参数
            List<(string, string, List<string>, string)> Ls_cfg_Par = m_ProxyInstance.Dic_proceduresPar[procedureName].Item5;
            //输入控制参数
            HTuple InputCtrlHTuple = AssemblyInstance.nC_Halcon.InputCtrlNames;

            //是否为新添加的参数标识
            bool isAdd = true;

            //遍历当前procedure的输入控制参数
            for (int i = 0; i < InputCtrlHTuple.Length; i++)
            {
              HTuple typeList = AssemblyInstance.nC_Halcon.GetHDevProcedureNC().GetInputCtrlParamInfo(i + 1, "type_list");
                //遍历字典中存储的procedure的输入控制参数
                for (int j = 0; j < Ls_cfg_Par.Count; j++)
                {
                    //判断参数包含cfg，且procedure的输入控制参数和字典中的一致，则不是新添加的参数
                    //
                    if (InputCtrlHTuple[i].S.ToLower().Contains("cfg") && InputCtrlHTuple[i].S == Ls_cfg_Par[j].Item1 && typeList == Ls_cfg_Par[j].Item4)
                    {
                        DataGridViewEdit.DataGridViewSet_Cfg(Ls_cfg_Par[j].Item1, Ls_cfg_Par[j].Item3.ToArray(), Ls_cfg_Par[j].Item4, dataGridView_Cfg);
                        isAdd = false;
                    }
                }

                if (InputCtrlHTuple[i].S.ToLower().Contains("cfg") && isAdd)
                {
                    //获取Halcon参数数组，做下拉框显示
                    HTuple values = AssemblyInstance.nC_Halcon.GetHDevProcedureNC().GetInputCtrlParamInfo(i + 1, "values");
                    //获取Halcon参数类型
                   // HTuple typeList = ExcuteHalconProc.nC_Halcon.GetHDevProcedureNC().GetInputCtrlParamInfo(i + 1, "type_list");

                    List<string> ls = new List<string>();
                    if (values?.Length > 1)
                    {
                        for (int k = 0; k < values.Length; k++)
                        {
                            ls.Add(values[k].S);
                        }
                        DataGridViewEdit.DataGridViewSet_Cfg(InputCtrlHTuple[i].S, ls.ToArray(), (typeList == null || typeList.Length == 0) ? "" : typeList.S, dataGridView_Cfg);
                    }
                    else
                    {
                        int rowIndex = dataGridView_Cfg.Rows.Add();
                        dataGridView_Cfg.Rows[rowIndex].Cells[0].Value = InputCtrlHTuple[i].S;
                        dataGridView_Cfg.Rows[rowIndex].Cells[2].Value = (typeList == null || typeList.Length == 0) ? "" : typeList.S;
                    }
                }
                isAdd = true;
            }
        }
        #endregion

        #region -------------DataGridView设置-----------------
        /// <summary>
        /// 防止寄存器不存在时，生成下拉框时报错
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Dgv_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            DataGridView dataGridView = sender as DataGridView;
            int rowIndex = e.RowIndex;
            int colIndex = e.ColumnIndex;
            dataGridView.Rows[rowIndex].Cells[colIndex].Value = "";

            //参数名称
            string parName = dataGridView.Rows[rowIndex].Cells[0].Value.ToString();
            MessageBox.Show($"参数{parName}的值无效，请检查存储位置ID是否存在");
        }

        /// <summary>
        /// 单元格数据变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            DataGridView dgv_table = sender as DataGridView;
            if (dgv_table.CurrentCell != null)
            {
                int row = dgv_table.CurrentRow.Index;
                int col = dgv_table.CurrentCell.ColumnIndex;
                //是否为选择框所在列
                if (col != 1)
                {
                    return;
                }

                string str = dgv_table.CurrentCell.EditedFormattedValue.ToString();
                if (str == "Tray")
                {
                    //选中Tray，后第一个单元格为textbox
                    DataGridViewTextBoxCell dataGridViewTextBoxCell = new DataGridViewTextBoxCell();
                    dgv_table.Rows[row].Cells[col + 1] = dataGridViewTextBoxCell;
                    //选中Tray，后第二个单元格为只读textbox
                    DataGridViewTextBoxCell dataGridViewTextBoxCell2 = new DataGridViewTextBoxCell();

                    dgv_table.Rows[row].Cells[col + 2] = dataGridViewTextBoxCell2;
                    dataGridViewTextBoxCell2.ReadOnly = true;

                }
                else if (str == "Register")
                {
                    //获取寄存器所有可用Id
                    int[] inputRegisterIds = NcPIDataRegisterManager.GetInputRegisterIDs();
                    DataGridViewComboBoxCell dataGridViewComboBoxCell = new DataGridViewComboBoxCell();
                    for (int i = 0; i < inputRegisterIds.Length; i++)
                    {
                        //获取寄存器数据格式
                        var properties = NcPIDataRegisterManager.GetRegisterProperties(inputRegisterIds[i]);
                        NcPIRegisterDataTypeInfo propertyInfo = properties.DataType;  //寄存器存储数据类型
                        NcPIDataRegisterManager.ReadFromRegister(inputRegisterIds[i], out object obj);   //寄存器存储的值
                                                                                                         //dataGridViewComboBoxCell.Items.Add(inputRegisterIds[i].ToString() + ":" + propertyInfo.ToString() + ":" + properties.Description + ":" + obj.ToString());
                        dataGridViewComboBoxCell.Items.Add(inputRegisterIds[i].ToString() + ":" + propertyInfo.ToString());
                    }
                    dgv_table.Rows[row].Cells[col + 1] = dataGridViewComboBoxCell;

                    DataGridViewButtonCell dataGridViewButtonCell = new DataGridViewButtonCell();

                    dgv_table.Rows[row].Cells[col + 2] = dataGridViewButtonCell;
                }
            }
        }
        /// <summary>
        /// 下拉设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            DataGridView dgv_table = sender as DataGridView;
            if (dgv_table.IsCurrentCellDirty)
            {
                dgv_table.CommitEdit(DataGridViewDataErrorContexts.Commit);
            }
        }
        /// <summary>
        /// 解决下拉菜单需要单击三次
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                DataGridView dataGridView = sender as DataGridView;
                if (e.RowIndex >= 0 && e.ColumnIndex >= 0 && !dataGridView.ReadOnly)
                {
                    //as 强转，判断是否为combox
                    DataGridViewComboBoxCell combo = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewComboBoxCell;
                    // DataGridViewComboBoxCell combo = new DataGridViewComboBoxCell();
                    if (combo != null)  //如果该列是ComboBox列
                    {
                        dataGridView.BeginEdit(false); //结束该列的编辑状态
                        DataGridViewComboBoxEditingControl comboEdite = dataGridView.EditingControl as DataGridViewComboBoxEditingControl;
                        if (comboEdite != null)
                        {
                            comboEdite.DroppedDown = true; //展现下拉列表
                        }
                    }

                    //判断是否为buttton
                    if ((dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewButtonCell) != null)
                    {
                        //当前为button，获取前一单元格值
                        DataGridViewComboBoxCell dataGridViewComboBoxCell = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex - 1] as DataGridViewComboBoxCell;
                        List<string> tempStr = new List<string>();
                        tempStr = GetRegisterInfo();
                        RegisterParDialog registerParDialog = new RegisterParDialog(tempStr);
                        registerParDialog.parEvent += (par) =>
                        {
                            string[] str = par.Split(':');
                            dataGridViewComboBoxCell.Value = string.Join(":", new string[] { str[0], str[1] });
                        };
                        registerParDialog.ShowDialog();

                        registerParDialog.parEvent -= (par) =>
                        {
                            string[] str = par.Split(':');
                            dataGridViewComboBoxCell.Value = string.Join(":", new string[] { str[0], str[1] });
                        };
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

        #region -----------------寄存器操作--------------
        /// <summary>
        ///获取寄存器列表信息
        /// </summary>
        /// <returns></returns>
        private List<string> GetRegisterInfo()
        {
            List<string> tempList = new List<string>();
            //获取寄存器所有可用Id
            int[] inputRegisterIds = NcPIDataRegisterManager.GetInputRegisterIDs();
            DataGridViewComboBoxCell dataGridViewComboBoxCell = new DataGridViewComboBoxCell();
            for (int i = 0; i < inputRegisterIds.Length; i++)
            {
                //获取寄存器数据格式
                var properties = NcPIDataRegisterManager.GetRegisterProperties(inputRegisterIds[i]);
                NcPIRegisterDataTypeInfo propertyInfo = properties.DataType;  //寄存器存储数据类型
                NcPIDataRegisterManager.ReadFromRegister(inputRegisterIds[i], out object obj);   //寄存器存储的值
                tempList.Add(inputRegisterIds[i].ToString() + ":" + propertyInfo.ToString() + ":" + properties.Description + ":" + obj.ToString());
            }
            return tempList;
        }

        #endregion

        #region ---------------单次运行，并显示图像---------------

        ShowResult showResult;
        HObject[] outputHobj = null;
        HTupleVector outputHtuple = new HTupleVector(1);
        HTuple type, pointer;
        HTuple width, height;
        int cmb_index = 0;   //默认显示第一个数据

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            btnRun.Enabled = checkBox1.Checked ? true : false;
            splitContainer1.Panel2Collapsed = checkBox1.Checked ? false : true;
            splitContainer1.SplitterDistance = 560;
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            splitContainer1.Panel2Collapsed = false;
            comboBox1.Items.Clear();

            showResult = ShowResult.GetInstance();
            showResult.TopLevel = false;
            panel3.Controls.Add(showResult);
            showResult.Dock = DockStyle.Fill;
            showResult.FormBorderStyle = FormBorderStyle.None;
            showResult.Show();


            m_ProxyInstance.Ls_control_Input = DataGridViewEdit.DataGridViewToList(dataGridView_Control_Input);
            string name = listBox_Procedures.SelectedItem.ToString();
            ExcuteHalcon.Excute(out outputHtuple, out outputHobj, dataGridView_Iconic_Input, dataGridView_Iconic_Output, dataGridView_Control_Input, dataGridView_Control_Output, dataGridView_Cfg, name);

            //是否有返回值
            if (outputHobj.Length < 0)
            {
                return;
            }
            if (comboBox1.Items.Count == 0)
            {
                for (int i = 0; i < outputHobj.Length; i++)
                {
                    comboBox1.Items.Add(dataGridView_Iconic_Output.Rows[i].Cells[0].Value.ToString());
                }
                comboBox1.SelectedIndex = cmb_index;
            }
        }
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmb_index = ((ComboBox)sender).SelectedIndex;
            HOperatorSet.GenEmptyObj(out HObject hObject);
            HOperatorSet.TestEqualObj(hObject, outputHobj[comboBox1.SelectedIndex], out HTuple isEqual);
            if (isEqual != 1)
            {
                //判断是否为image
                if (comboBox1.SelectedItem.ToString().ToLower().Contains("image"))
                {
                    HOperatorSet.GetImagePointer1(outputHobj[comboBox1.SelectedIndex], out pointer, out type, out width, out height);
                    HWindow Window = showResult.hSmartWindowControl1.HalconWindow;
                    // Window.SetPart(0, 0, height.I, width.I);
                }
                else
                {
                    //int a = outputHobj[comboBox1.SelectedIndex].CountObj();
                    //for (int i = 0; i < a; i++)
                    //{
                    //    HOperatorSet.ConcatObj(HalconRoi, outputHobj[comboBox1.SelectedIndex], out HalconRoi);
                    //}
                    //HOperatorSet.RegionFeatures(HalconRoi, "width", out width);
                    //HOperatorSet.RegionFeatures(HalconRoi, "height", out height);

                }
            }
            else
            {
                MessageBox.Show($"{comboBox1.SelectedItem.ToString()}为空");
                return;
            }

            //不是image，直接显示
            showResult.hSmartWindowControl1.HalconWindow.ClearWindow();
            showResult.hSmartWindowControl1.HalconWindow.DispObj(outputHobj[comboBox1.SelectedIndex]);
        }
        #endregion

    } // end of class
} // end of namespace